<?php

namespace App\Services\Pay\GuoTonXinYi;

use App\Common\PaySuccessAction;
use App\Common\RefundSuccessAction;
use App\Models\Order;
use App\Models\RefundOrder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class Notify
{


    const Key = "88888888";

//{"CUST_ID":"60000000967100","PAY_TYPE":"","THREE_ORDER_NO":"827055035784187904_SFK","sign":"ebXfVw4T4U6R3kAVWO73+yCc1pNRrRDCNYXPf6cWlXmDY+KLJJtb8cJcH5Gh9kIAVvWg2V9HtgDVhCXw8F9hLqeLDykhWp4Lbty8d7x2MDkTAYrMD9jXqjAWODXRkHls+U4s6fu/0qrdGCQ8C0+AHtL2/6dcvyDxHNZ9bE6VEGw3SumcLMtSsRgt3LaO7lBQ0eZ+JRxXq+ILLFhYXHqXiCzYdfwcCM69M46t9APwoNMTraNxBHlzHX7RAuuZUIArYtcedyHJNwnvE3BFbC4sGtX3TOV2Kw3ls0F+2f9Jyjl0bU+kUAJ42id2woYGia8nFa5wCkVSfc8kNa7ENmjWBA==","CARD_TYPE":"03","ORDER_NO":"20230609SS1theoe","T_ORDER_NO":"20230609154818003515","DEVICE_NO":"99999999","AGET_ID":"61000000105292","ORDER_TIME":"20230609154833","ORDER_STATUS":"1","CODE_AGE_AMT":"","DISCOUNT_FEE":"0","BANK_CODE":"OTHERS","REMARK":"","PROMOTION_DETAIL":"","PAY_CHANNEL":"2","DISCOUNT_FLAG":"0","DEBT_STATE":"","PAY_WAY":"2","TXAMT":"5","NETR_AMT":"5","OPEN_ID":"oUpF8uIb1dBhsoJOTxqC0ELmGz9M","MERCH_CONTRIBUTE":"","CUST_AMT":"0","TRADING_IP":"195.25.45.1","CUST_FEE":"0","USTLDAT":"","T_PAY_NO":"4200067684202306091693628726","BUSI_DATA":"","ORDER_TIME":"20230609154833","BANK_NAME":"零钱通或零钱"}
    public static function notifyUrl(Request $request): \stdClass
    {
        $out_trade_no = $request->post("THREE_ORDER_NO");
        try {
            $pay_method = $request->post("PAY_WAY");
            $pay_time = $request->post("ORDER_TIME");
            $order_status = $request->post("ORDER_STATUS");
            //1.支付成功、e.数币成功、4.退款成功、5.退款中、7.刷卡撤销成功、14.预授权成功、16.预授权撤销成功、98.刷卡撤销中、a.担保成功、c.担保撤销成功 （注：预授权完成成功、担保完成成功，是属于1.支付成功；预授权完成撤销成功、担保完成撤销成功是属于4.退款成功； 数币退款成功是属于4.退款成功，数币退款中属于5.退款中）
            $pay_type = $request->post("PAY_CHANNEL");
//            $trade_no = $request->post("T_PAY_NO", "");
            $trade_no=$request->post("ORDER_NO", "");
            Log::channel("gtxy")->info("notifyUrl-" . $out_trade_no, $request->all());
            //签名计算
            $data = $request->all();
            $sign = $data["sign"];
            unset($data["sign"]);
            if (!Config::checkSign($data, $sign)) {
                Log::channel("gtxy")->info("checkSign-" . $out_trade_no, ["error"]);
                throw new \Exception("签名校验失败");
            }
            //走正常逻辑
            $order = Order::query()->where("out_trade_no", $out_trade_no)->first();
            if (empty($order)) {
                throw new \Exception("订单不存在");
            }
            switch ((int)$order_status) {
                case 1:
//                    1.支付成功、e.数币成功
                    if ($order->pay_status != 1 && $order->pay_status != 6) {
                        //已经支付成功
                        $order->pay_status = 1;
                        $order->pay_status_desc = "支付成功";
                        $order->pay_time = date("Y-m-d H:i:s", strtotime($pay_time));
                        $order->trade_no = $trade_no;
//                        $order->other_no = $other_no;
                        $order->buyer_pay_amount = $request->post("NETR_AMT", 0) / 100;
                        $order->buyer_logon_id = $request->post("OPEN_ID", "");
                        $order->buyer_id = $request->post("OPEN_ID", "");
                        $order->save();
                        \App\Common\PaySuccessAction::addCoupon($order->out_trade_no, $request->post("PROMOTION_DETAIL",""), 'pay');
                        PaySuccessAction::action($order->toArray());
                        //支付成发送通知
                        self::handleNotifyUrl($order);
                    }
                    break;
//                case 4:
//                    break;
                default:
                    throw new \Exception("回调状态异常");
            }
            Log::channel("gtxy")->info("notifyUrl-response" . $out_trade_no, $request->all());
            $responseObject = new \stdClass();
            $responseObject->rspCod = "";
            $responseObject->rspMsg = "success";
            return $responseObject;
        } catch (\Exception $e) {
            Log::channel("gtxy")->info("notify-error-" . $out_trade_no, [
                "req" => $request->all(),
                "error" => $e->getMessage()
            ]);
            $responseObject = new \stdClass();
            $responseObject->rspCod = "";
            $responseObject->rspMsg = "fail";
            return $responseObject;
        }
    }

    protected static function handleNotifyUrl(Order $order): void
    {
        if (!empty($order->notify_url)) {
            $trade_no = isset($data['transactionId']) ? $data['transactionId'] : "";
            $array = array(
                'return_code' => 'SUCCESS',
                'return_msg' => '返回成功',
//                'other_no' => $order->other_no,
                'store_id' => $order->store_id,
                'result_code' => 'SUCCESS',
                'result_msg' => '支付成功',
                'out_trade_no' => $order->out_trade_no,
                'out_transaction_id' => $trade_no,
                'trade_no' => $order->trade_no,
                'pay_time' => $order->pay_time,
                'ways_source' => $order->ways_source,
                'pay_amount' => $order->pay_amount,
                'total_amount' => $order->total_amount,
                'ways_source_desc' => $order->ways_source_desc,
            );
            try {
                $notify_url = $order->notify_url;
                $in_data = $array;
                unset($in_data['sign']);
                $string = self::getSignContent($in_data) . '&key=' . self::Key;
//                $in_data['other_no'] = $order->other_no;
                $in_data['sign'] = md5($string);
                if (strpos($notify_url, '?') !== false) {
                    $notify_url = $notify_url . '&' . self::getSignContent($in_data);
                    self::curlPost_java(json_encode($in_data), $notify_url);
                } else {
                    $notify_url = $notify_url . '?' . http_build_query($in_data);
                    self::curlPost_java(json_encode($in_data), $notify_url);
                }
            } catch (\Exception $exception) {
                Log::channel()->info("handleNotifyUrl", [
                    "通知商户失败",
                    $exception->getMessage(),
                    $exception->getFile(),
                    $exception->getLine()
                ]);
            }
        }
    }


    protected static function checkEmpty($value)
    {
        if (!isset($value)) {
            return true;
        }
        if ($value === null) {
            return true;
        }
        if (trim($value) === "") {
            return true;
        }
        return false;
    }

    //参数拼接
    public static function getSignContent($params)
    {
        ksort($params);
        $stringToBeSigned = "";
        $i = 0;
        foreach ($params as $k => $v) {
            if (false === self::checkEmpty($v) && "@" != substr($v, 0, 1)) {
                // 转换成目标字符集
                // $v = $this->characet($v, $this->postCharset);
                if ($i == 0) {
                    $stringToBeSigned .= "$k" . "=" . "$v";
                } else {
                    $stringToBeSigned .= "&" . "$k" . "=" . "$v";
                }
                $i++;
            }
        }
        unset ($k, $v);
        return $stringToBeSigned;
    }


    /**
     * curl post java对接  传输数据流
     * */
    public static function curlPost_java($data, $Url)
    {
        $ch = curl_init($Url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//$data JSON类型字符串
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($data)));
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
}